home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
bix02.arc
/
TSETS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1986-08-04
|
5KB
|
168 lines
(*Turbo/Generic - assorted procs/funcs for set operations on sets of 0..2039
For those few of you for whom Turbo's 0..255 is too restrictive, here's
a collection of routines that treat a 'string[255]' as a superset of 0..2039.
There's a procedure 'show' that display a set's elements as well as a text
message. For ease of coding, there's a routine 'Lit' that, given a normal
set literal (i.e. [1,7,34..55,178..202]) returns a LongSet. Since you cannot
have an element greater than 255 in normal Turbo sets, to set additional
elements you do "S1 := SetOn(S1,1987)" which is equivalent to "s1:=s1+[1987]"
IF Turbo handled such large numbers.
The program contains some examples of usage. The first few examples have
as comments the equivalent set operation expression for normal sets. The last
dozen examples display set contents on the screen after various operations.
It's suggested that you have a printout of the source while you're viewing
the screen's display to get a flavor for proper usage. - Jim Keohane*)
Program TSets;
TYPE LongSet=STRING[255];
LitSet= set of 0..255;
str40=string[40];
VAR S1,S2,S3:LongSet;
i:integer;
Procedure LongEnuf(I:Integer;var LS:LongSet);
begin
if i > length(LS) then
begin
FillChar(LS[succ(length(ls))],i-length(ls),0);
ls[0]:=chr(i)
end
end;
Function SetOff(LS:LongSet;I:Integer):LongSet;
var j:integer;
begin
j:=1+I shr 3;
if j> Length(LS) then LongEnuf(j,LS);
ls[j]:=chr(ord(ls[j]) and ($ff7f shr (7-(i and $7))));
SetOff:=ls
end;
Function SetOn(LS:LongSet;I:Integer):LongSet;
var j:integer;
begin
j:=1+I shr 3;
if j> Length(LS) then LongEnuf(j,LS);
ls[j]:=chr(ord(ls[j]) or ($0080 shr (7-(i and $7))));
SetOn:=ls
end;
Function InSet(I:integer;S:LongSet):boolean;
var j:integer;
begin
j := 1 + i shr 3;
if j >length(s) then InSet:=false else
InSet:=ord(s[j]) and ($0080 shr (7-(i and $7))) <> 0
end;
Function Union(S1,S2:LongSet):LongSet;
var s:longset;
i:integer;
begin
s:=s1;
if length(s1)<length(s2) then LongEnuf(length(s2),s);
for i:=1 to length(s2) do s[i]:=chr(ord(s[i]) or ord(s2[i]));
Union:=s
end;
Function Diff(S1,S2:LongSet):LongSet;
var s:longset;
i:integer;
begin
s:=s1;
for i:=1 to length(s) do s[i]:=chr(ord(s[i]) and (not ord(s2[i])));
Diff:=s
end;
Function Intersect(S1,S2:LongSet):LongSet;
var s:longset;
i:integer;
begin
if length(s1)<length(s2) then s[0]:=s1[0] else s[0]:=s2[0];
for i:=1 to length(s) do s[i]:=chr(ord(s1[i]) and ord(s2[i]));
while (s[0]>#0) and (s[length(s)]=#0) do s[0]:=pred(s[0]);
Intersect:=s
end;
Function Lit(l:litset):LongSet;
var s:longset;
begin
s[0]:=' ';
move(l,s[1],32);
while (s[0]>#0) and (s[length(s)]=#0) do s[0]:=pred(s[0]);
Lit:=s
end;
Function Leq(S1,S2:LongSet):boolean;
begin
if s1=s2 then Leq:=true else
Leq := s1 = Intersect(s1,s2)
end;
Function Geq(S1,S2:LongSet):boolean;
begin
if s1=s2 then Geq:=true else
Geq := s2 = Intersect(s1,s2)
end;
Procedure Show(txt:str40;S:LongSet);
var i,j:integer;
begin
j:=length(s) shl 3 -1;
write(txt,' ':40-length(txt));
for i:=0 to j do if inset(i,s) then write(i:8);
writeln
end;
BEGIN
S1 := ''; {S1 := [] }
S1 := SetOn(S1,100); { S1 := S1 + [100] }
S2 := S1; {straight assignment}
IF InSet(100,S1) THEN; {IF 100 IN S1 }
S1 := SetOff(S1,100); { S1 := S1 - [100] }
S3 := Union(S1,S2); { S1 := S1 + S2 }
S3 := Intersect(S1,S2); { S3 := S1 * S2 }
S3 := Diff(S1,S2); {S3 := S1 - S2 }
IF S2 = S3 then; {if s2 = s3 }
IF Leq(S1,s2) then; { if s1 <= s2 }
IF Geq(S1,S2) then; { if s1>=s2 }
S3 := Lit([1,5,35..78,126]); { s3 := [1,5,35..78,126] }
IF Intersect(S1,S2)='' then; { if s1*s2=[] }
{test some routines}
S1:='';
show('null',s1);
s1:=lit([1..5,200,232]);
show('[1..5,200,232]',s1);
s1:='';
s1:=seton(s1,1);s1:=seton(s1,2);s1:=seton(s1,3);s1:=seton(s1,4);
s1:=seton(s1,5);s1:=seton(s1,200);s1:=seton(s1,232);
show('[1..5,200,232]',s1);
s2:=lit([199..201]);
s3:=union(s1,s2);
show('[1..5,199..201,232]',s3);
s3:=intersect(s1,s2);
show('[200]',s3);
show('s1=',s1);
show('s2=',s2);
if not geq(s1,s2) then writeln('s1 IS NOT >= s2');
s2:=setoff(s2,199);
s2:=setoff(s2,201);
show('s2 is now = to ',s2);
if geq(s1,s2) then writeln('s1 IS NOW >= s2');
s1:='';
for i:= 2000 to 2010 do s1:=seton(s1,i);
show('2000 thru 2010',s1);
s2:='';s2:=seton(s2,2005);
s3:=diff(s1,s2);
show('2000..2004,2006..2010',s3);
s3:=setoff(s3,2006);
show('2000..2004,2007..2010',s3);
end.